package main

import (
	"gitee.com/flycash/xiaohongshu-demo/internal/repository"
	"gitee.com/flycash/xiaohongshu-demo/internal/repository/cache"
	"gitee.com/flycash/xiaohongshu-demo/internal/repository/dao"
	"gitee.com/flycash/xiaohongshu-demo/internal/service"
	"gitee.com/flycash/xiaohongshu-demo/internal/web"
	"gitee.com/flycash/xiaohongshu-demo/internal/web/middleware"
	iplimiter "github.com/Salvatore-Giordano/gin-redis-ip-limiter"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"go.uber.org/zap"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	gormLogger "gorm.io/gorm/logger"
	"log"
	"os"
	"time"
)

func main() {
	logger, err := zap.NewDevelopment()
	if err != nil {
		panic(err)
	}

	bDB, err := gorm.Open(mysql.Open("root:root@tcp(localhost:13316)/xiaohongshu_b"),
		&gorm.Config{
			Logger: gormLogger.New(log.New(os.Stdout, "制作库", log.LstdFlags),
				gormLogger.Config{
					SlowThreshold:             0 * time.Millisecond,
					IgnoreRecordNotFoundError: true,
					ParameterizedQueries:      true,
					LogLevel:                  gormLogger.Info,
				}),
		})
	if err != nil {
		panic(err)
	}

	err = bDB.AutoMigrate(&Article{})
	if err != nil {
		panic(err)
	}

	cDB, err := gorm.Open(mysql.Open("root:root@tcp(localhost:13316)/xiaohongshu_c"))
	if err != nil {
		panic(err)
	}

	cDB.Callback().Create().Before("*").
		Register("slow_query_create_start", func(db *gorm.DB) {
			db.Set("start_time", time.Now())
		})

	cDB.Callback().Create().After("*").
		Register("slow_query_create_end", func(db *gorm.DB) {
			startTime, ok := db.Get("start_time")
			if ok {
				duration := time.Since(startTime.(time.Time))
				logger.Error("慢查询",
					zap.String("sql", db.Statement.SQL.String()),
					zap.Duration("duration", duration),
				)
			}
		})

	err = cDB.AutoMigrate(&Article{})
	if err != nil {
		panic(err)
	}

	redisClient := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       1,
	})
	artCache := cache.NewRedisArticleCache(redisClient)

	server := gin.Default()
	server.Use(
		iplimiter.NewRateLimiterMiddleware(redisClient, "general", 200, 60*time.Second),
		middleware.NewLogMiddlewareBuilder(logger).Build(),
	)
	server.LoadHTMLGlob("./templates/*.gohtml")

	bArtDAO := dao.NewArticleDAO(bDB)
	bArtRepo := repository.NewArticleRepository(bArtDAO, artCache)

	cArtDAO := dao.NewArticleDAO(cDB)
	cArtRepo := repository.NewArticleRepository(cArtDAO, artCache)

	artSvc := service.NewArticleService(bArtRepo, cArtRepo)
	artCtrl := web.NewArticleController(artSvc)
	artCtrl.RegisterRoutes(server)

	if err = server.Run(":8080"); err != nil {
		panic(err)
	}
}

type Article struct {
	Id int64 `gorm:"primaryKey,autoIncrement"`
	// 存的是作者的用户 ID
	Author  int64  `gorm:"not null"`
	Title   string `form:"title"`
	Content string `form:"content"`
	Ctime   int64
	Utime   int64
}
